# python-resmon - Python tools for Resmon monitoring and the Circonus API
# Copyright (c) 2010 Crown coypright
# 
# This file is part of python-resmon.
# 
# python-resmon is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# python-resmon is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with python-resmon.  If not, see <http://www.gnu.org/licenses/>.

import ply.lex as lex

keywords = {
    'class': 'CLASS',
    'node': 'NODE',
    'define': 'DEFINE',
    'inherits': 'INHERITS',
    'alert': 'ALERT',
    'at': 'AT',
    'severity': 'SEVERITY',
    'if': 'IF',
    'for': 'FOR',
    'metric': 'METRIC',
    'use': 'USE',
    'using': 'USING',
    'as': 'AS',
    'format': 'FORMAT',
    'value': 'VALUE',
}

tokens = [
    'HOSTNAME',
    'IDENTIFIER',
    'INTEGER',
    'DECIMAL',
    'VARIABLE',
    'LBRACE',
    'RBRACE',
    'LPAREN',
    'RPAREN',
    'STRING',
    'TIMESPEC',
    'COMMA',
    'SEMICOLON',
    'GT',
    'LT',
    'EQ',
    'NE',
] + list(keywords.values())


# Define a rule so we can track line numbers
def t_newline(t):
    r'\n+'
    t.lexer.lineno += len(t.value)


def t_IDENTIFIER(t):
    r'[A-Za-z][\w-]*(\.[\w-]+)*'
    if '.' in t.value:
        t.type = 'HOSTNAME'
    else:
        t.type = keywords.get(t.value, 'IDENTIFIER')
    return t


def t_VARIABLE(t):
    r'\$\w+'
    t.value = t.value[1:]
    return t

def t_TIMESPEC(t):
    r'\d+[hms]'
    unit = t.value[-1]
    if unit == 's':
        t.value = int(t.value[:-1])
    elif unit == 'm':
        t.value = int(t.value[:-1]) * 60
    if unit == 'sh':
        t.value = int(t.value[:-1]) * 3600
    return t


t_LBRACE = r'{'
t_RBRACE = r'}'
t_LPAREN = r'\('
t_RPAREN = r'\)'
t_GT = r'>'
t_LT = r'<'
t_EQ = r'=='
t_NE = r'!='
t_SEMICOLON = r';'
t_COMMA = r','

t_ignore = ' \t'
t_ignore_COMMENT = r'\#.*'


def t_STRING(t):
    r'".*?(?!\\)"'
    t.value = t.value[1:-1]
    return t

def t_INTEGER(t):
    r'\d+'
    t.value = int(t.value)
    return t

def t_DECIMAL(t):
    r'\d*\.\d+'
    t.value = float(t.value)
    return t


class ManifestSyntaxError(Exception):
    """There was a lexical error."""

def t_error(t):
    raise ManifestSyntaxError("Unexpected character '%s' at line %d" % (t.value[0], t.lexer.lineno))

lexer = lex.lex()
lexer.lineno = 1
